﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using AMM.Model;
using AMM.Model.Project;

namespace AMM.DataAccess.Project {
    public class ProductRepository : BaseRepository<Product> {

        private int _pageSize;

        public ProductRepository(int pageSize) {
            this._pageSize = pageSize;
        }

        public Product FetchProductById(int productId) {
            using (var ctx = this.Context) {
                return ctx.Products.Find(productId);
            }
        }

        public List<Product> FetchProductList() {
            using (var ctx = this.Context) {
                return ctx.Products.Include("Basic").ToList();
            }
        }

        public void Update(Product product, Product oldProduct) {
            using (var ctx = this.Context) {
                using (DbContextTransaction trans = ctx.Database.BeginTransaction()) {
                    try {
                        if (oldProduct.AttachmentId.HasValue) {
                            Attachment oldAttachment = ctx.Attachments.Find(oldProduct.AttachmentId);
                            oldAttachment.IsLinked = false;
                            ctx.Attachments.Attach(oldAttachment);
                            ctx.Entry(oldAttachment).State = EntityState.Modified;
                        }
                        if (product.AttachmentId.HasValue) {
                            Attachment newAttachment = ctx.Attachments.Find(product.AttachmentId);
                            newAttachment.IsLinked = true;
                            ctx.Attachments.Attach(newAttachment);
                            ctx.Entry(newAttachment).State = EntityState.Modified;
                        }
                        ctx.Products.Attach(product);
                        ctx.Entry(product).State = EntityState.Modified;
                        ctx.SaveChanges();
                        trans.Commit();
                    }
                    catch (Exception ex) {
                        trans.Rollback();
                        throw ex;
                    }
                }
            }
        }

        public List<Product> FetchProductList(ProductSearchModel searchModel, int pageIndex) {
            using (var ctx = this.Context) {
                var query = ctx.Products
                    .Include("Basic")
                    .Include("Basic1")
                    .Where(x => !string.IsNullOrEmpty(x.Code));

                if (!string.IsNullOrEmpty(searchModel.Code)) {
                    query = query.Where(x => x.Code.Contains(searchModel.Code));
                }
                if (!string.IsNullOrEmpty(searchModel.Name)) {
                    query = query.Where(x => x.Name.Contains(searchModel.Name));
                }
                if (searchModel.ProductTypeId.HasValue) {
                    query = query.Where(x => x.ProductTypeId == searchModel.ProductTypeId.Value);
                }
                if (searchModel.IsEnabled.HasValue) {
                    query = query.Where(x => x.IsEnabled == searchModel.IsEnabled.Value);
                }
                if (searchModel.IsSelfFinished.HasValue) {
                    query = query.Where(x => x.IsSelfFinished == searchModel.IsSelfFinished.Value);
                }

                searchModel.Records = query.Count();
                pageIndex = (pageIndex - 1) * this._pageSize > searchModel.Records ? 1 : pageIndex;

                return query.OrderByDescending(x => x.Code).Skip((pageIndex - 1) * this._pageSize).Take(this._pageSize).ToList();
            }
        }

        public void DeleteMultipleProduct(params int[] productIds) {
            using (var ctx = this.Context) {
                using (DbContextTransaction trans = ctx.Database.BeginTransaction()) {
                    try {
                        ctx.Products.Where(x => productIds.Contains(x.ProductId)).ToList().ForEach(x => {
                            ctx.Products.Remove(x);
                        });
                        ctx.SaveChanges();
                        trans.Commit();
                    }
                    catch (Exception ex) {
                        trans.Rollback();
                        throw ex;
                    }
                }
            }
        }
    }
}
